<?php

declare(strict_types=1);

namespace app\utils;

// 引入框架内置类
use think\facade\Db;
use think\facade\Config;

/**
 * 验证 utils
 *
 * @version      0.0.1
 * @author      by huwhois
 * @time        20228/10
 */
class ValidateUtils
{
    protected $namespace;
    protected $class;
    protected $tableName;
    protected $databaseName;

    protected function getPathName(string $name): string
    {
        $name = substr($name, 4);

        return app()->getBasePath() . ltrim(str_replace('\\', '/', $name), '/') . '.php';
    }

    protected function getStub(): string
    {
        return __DIR__ . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'validate.stub';
    }

    /**
     * 获取表的所有字段信息
     * @return array
     */
    protected function getColumns()
    {
        $sql = "SELECT column_name,column_comment,data_type FROM information_schema.COLUMNS WHERE TABLE_NAME = '" . $this->tableName . "' AND table_schema = '" . $this->databaseName . "'";

        // echo $sql . "\n";

        $res = Db::query($sql);

        $columns = empty($res) ? [] : $res;

        return $columns;
    }

    /**
     * 构建Class文件
     * @return string
     */
    protected function buildClass()
    {
        $stub = file_get_contents($this->getStub());

        $schemas = '';

        $columns = $this->getColumns();

        foreach ($columns as $column) {
            $schemas .= "\n" . '        "' . $column['column_name'] . '" => "require",';
        }

        return str_replace(['{%namespace%}', '{%className%}', '{%schemas%}'], [
            $this->namespace,
            $this->class,
            $schemas
        ], $stub);
    }

    /**
     * 生成 Model 文件
     * @param  string $name 类目，包含命名空间
     * @param string $connections 数据库配置, 默认 mysql
     */
    public function makeModel(string $name, string $connections = 'mysql')
    {
        $pathname = $this->getPathName($name);

        if (is_file($pathname)) {
            throw new \Exception("Valiate :' . $name . ' already exists!</error>", 1);
        }

        if (!is_dir(dirname($pathname))) {
            mkdir(dirname($pathname), 0755, true);
        }

        file_put_contents($pathname, $this->codeModel($name, $connections));
    }

    /**
     * 生成 Model 不生成文件
     * @param  string $name 类目，包含命名空间
     * @param string $connections 数据库配置, 默认 mysql
     * @return string
     */
    public function codeModel(string $name, string $connections = 'mysql')
    {
        $this->namespace = trim(implode('\\', array_slice(explode('\\', $name), 0, -1)), '\\');

        $this->class = str_replace($this->namespace . '\\', '', $name);

        $this->tableName = Config::get('database.connections.'.$connections.'.prefix') . strtolower(preg_replace('/(?<=[a-z])([A-Z])/', '_$1', $this->class));

        $this->databaseName = Config::get('database.connections.'.$connections.'.database');

        return $this->buildClass();
    }
}
